package com.yz.jdd.base.utils;

import android.content.Intent;
import android.text.TextUtils;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.yz.jdd.base.MyApplication;
import com.yz.jdd.base.event.Events;
import com.yz.jdd.base.event.RxBus;
import com.yz.jdd.module.launch.model.H5Module;
import com.yz.jdd.network.NetWorkRequset;
import com.yz.jdd.webview.download.H5DownFileUtils;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import okhttp3.ResponseBody;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * Created by cc on 2017/3/20.
 */

public class H5Utils {


    private static Map<String, String>  jsonMap;

    public static boolean writeResponseBodyToDisk(ResponseBody body, String downloadName, H5Module module) {


        InputStream inputStream = null;
        OutputStream outputStream = null;
        long fileSize = body.contentLength();
        final String md5Str=module.getHashcode();
        try {
            URL mUrl = new URL(downloadName);
            String fileName = new File(mUrl.getFile()).getName();

            String dirPath = H5DownFileUtils._ZIP_FOLDERPATH ;
            File file = new File(dirPath);
            if (!file.exists()) {
                file.mkdirs();
            }
            File zipFile= new File(dirPath, fileName);
//        if (!filePath.exists()) {
//            try {
//                filePath.createNewFile();
//            } catch (IOException e) {
//                // TODO Auto-generated catch block
//                e.printStackTrace();
//            }
//        }


            LogUtils.Log("h5", "zippath="+zipFile.getAbsolutePath());
//        File futureFile = new File(path);
            try {
                byte[] fileReader = new byte[1024 * 1024];
                long fileSizeDownloaded = 0;
                inputStream = body.byteStream();
                outputStream = new FileOutputStream(zipFile);

                while (true) {
                    int read = inputStream.read(fileReader);

                    if (read == -1) {
                        break;
                    }
                    outputStream.write(fileReader, 0, read);
                    fileSizeDownloaded += read;

                }
                LogUtils.Log("h5", "file download: " + fileSizeDownloaded + " of " + fileSize);
                outputStream.flush();
                //验证MD5值，确保下载完成

                String modelMD5=MD5Util.getFileMD5(zipFile);
                LogUtils.Log("h5", "net md5=" + md5Str);
                LogUtils.Log("h5", "download md5=" + modelMD5);
//                if(!TextUtils.isEmpty(md5Str)&&md5Str.equals(modelMD5)){

                    //解压到哪个目录
                    if(true){
                    File dirFile=new File(H5DownFileUtils._UPZIP_FOLDERPATH+"/"+module.getName());
                    File dirFileTemp=new File(H5DownFileUtils._UPZIP_FOLDERPATH+"/"+module.getName()+"temp");
                    boolean reNameDir = false;
                    if(dirFile.exists()&&dirFile.isDirectory()){
                            reNameDir= dirFile.renameTo(dirFileTemp);
                    }
                    boolean upZipSuccess= H5DownFileUtils.upZipFile(zipFile, H5DownFileUtils._UPZIP_FOLDERPATH, "");
                    if(upZipSuccess){
                        //解压完成删掉zip
                        if(zipFile!=null&&zipFile.exists())
                        zipFile.delete();
                        deleteFile(dirFileTemp);
                    }else{
                        if(reNameDir){
                            dirFileTemp.renameTo(dirFile);
                        }
                    }
                    LogUtils.Log("h5", "download upzip" + upZipSuccess);
                   return upZipSuccess;
                }else{
                    //MD5 不同就删掉
                    if(zipFile!=null&&zipFile.exists())
                    zipFile.delete();
                    return false;
                }
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            }
        } catch (IOException e) {
            return false;
        }

    }
    /**
     * 递归删除文件和文件夹
     *
     * @param file
     *            要删除的根目录
     */
    public static boolean deleteFile(File file) { // //
        boolean flag = true;
        if (file.exists() == false) {
            return flag;
        } else {
            if (file.isFile()) {
                flag = file.delete();
                return flag;
            } else {
                File[] childFile = file.listFiles();
                if (childFile == null || childFile.length == 0) {
                    flag = file.delete();
                    return flag;
                }
                for (File f : childFile) {
                    deleteFile(f);
                }
                flag = file.delete();
                return flag;
            }
        }
        // return true;
    }


    public static void downLoadH5Model(List<H5Module> h5Module){

//
//        List<Observable<Boolean>> observables = new ArrayList<Observable<Boolean>>();
//
//        final Map<String, String> jsonMap = new HashMap<String, String>();

        List<Observable<Boolean>> observables = new ArrayList<Observable<Boolean>>();
        //取一下历史版本
        String vs = PreferencesUtils.getString(MyApplication.application, BaseConfigs.PREFS_STR_H5, "");
//        LogUtils.Log("lkf", "get from sp==h5utils" + vs);
        Gson gson = new Gson();
        if(!TextUtils.isEmpty(vs)){

            jsonMap = gson.fromJson(vs, new TypeToken<Map<String, String>>() {
            }.getType());
        }else{
            jsonMap = new HashMap<String, String>();
        }

        //将所有的Observable放到List中
        for (int i = 0; i < h5Module.size(); i++) {
            final H5Module module=h5Module.get(i);
            final String downloadUrl = module.getAddress();


            final Map<String, String> finalJsonMap = jsonMap;
            observables.add(
                    NetWorkRequset.downloadH5zip(downloadUrl).subscribeOn(Schedulers.io())
                    .map(new Func1<ResponseBody, Boolean>() {
                        @Override
                        public Boolean call(ResponseBody responseBody) {
                                //下载、解压
                            boolean success=writeResponseBodyToDisk(responseBody,downloadUrl,module);
                            if(success)
                                finalJsonMap.put(module.getName(), module.getVersion());
                            return success;

                        }
                    }).subscribeOn(Schedulers.io()));
        }

        //Observable的merge将所有的Observable合成一个Observable,所有的observable同时发射数据。
        Observable.merge(observables).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Boolean>() {
                    @Override
                    public void onCompleted() {
                        LogUtils.Log("h5", "MainActivity.download.times=====onCompleted");
                        Gson gson = new Gson();
                        String jsonStr = gson.toJson(jsonMap);
                        LogUtils.Log("h5", "put=" + jsonStr);
                        PreferencesUtils.putString(
                                MyApplication.application,
                                BaseConfigs.PREFS_STR_H5, jsonStr);
                        PreferencesUtils.putBoolean(MyApplication.application,
                                BaseConfigs.BOOLEAN_H5MODULE,true);

//                        RxBus.getInstance().send(Events.EVENT_LOAD_URL,"");
                        //发消息给子进程 H5 页面
                        Intent intent = new Intent("updateH5Page");
                        intent.putExtra("event", Events.EVENT_LOAD_URL);
                        MyApplication.application.sendBroadcast(intent);

                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }

                    @Override
                    public void onNext(Boolean b) {
                        if (b) {
                            LogUtils.Log("h5", "MainActivity.download.times=====");

                        }
                    }
                });
    }
}
